#import "MRRefreshControl.h"

#define     ANIMATEDURATION     0.3

/*===================================================================
 说明:
    刷新视图
 ==================================================================*/
@implementation MRRefreshView

- (void)awakeFromNib
{
	[super awakeFromNib];
	
	_indView.transform   = CGAffineTransformMakeScale(0.73, 0.73);
	_imgArrow.transform  = CGAffineTransformMakeRotation(self.tag ? M_PI : 0);
	_labStatus.textColor = [UIColor grayColor];
	
	self.language = self.tag ? @"CTR_LOADING" : @"CTR_REFRESH";
}

- (void)didLanguage
{
	self.aryString = L(self.language);
}

- (void)setAryString:(NSString *)aryString
{
    _aryString = aryString;
    [self setInfoText:[_aryString componentsSeparatedByString:@","][_status]];
}

- (void)setInfoText:(NSString *)text
{
    _labStatus.text = text;
    
    CATransition *animation = [CATransition animation];
    [animation setDuration:ANIMATEDURATION];
    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];
    //[animation setType:@"oglFlip"];
    [animation setType:kCATransitionFade];
    //[animation setSubtype:kCATransitionFromLeft];
    [_labStatus.layer addAnimation:animation forKey:nil];
}

- (void)setStatus:(MRRefreshStatus)status
{
    if (status == _status) return;
    _status = status;
	
    switch (_status)
    {
        case MRRefreshNormal: {
            [self setInfoText:[_aryString componentsSeparatedByString:@","][0]];
            _imgArrow.hidden = NO;
            [_indView stopAnimating];
            [UIView animateWithDuration:ANIMATEDURATION animations:^{
				_imgArrow.transform = CGAffineTransformMakeRotation(self.tag ? M_PI : 0);
            }];
        } break;
            
        case MRRefreshRelease: {
            [self setInfoText:[_aryString componentsSeparatedByString:@","][1]];
            [UIView animateWithDuration:ANIMATEDURATION animations:^{
                _imgArrow.transform = CGAffineTransformMakeRotation(self.tag ? 0 : M_PI);
            }];
        } break;
            
        case MRRefreshWorking: {
            [self setInfoText:[_aryString componentsSeparatedByString:@","][2]];
            _imgArrow.hidden = YES;
            _imgArrow.transform = CGAffineTransformMakeRotation(self.tag ? M_PI : 0);
            [_indView startAnimating];
        } break;
    }
}

@end

#pragma mark - 刷新控件
@implementation MRRefreshControl
{
	BOOL    isBusy, isEndLoad;
	
	id      _target[3];
	SEL     _action[3];
}

/*===================================================================
 说明:
    初始化
 ==================================================================*/
- (id)initWithScrollView:(UIScrollView *)scrollView
{
    if (self = [super init])
    {
		_scrollView = scrollView;
		_edgeInset  = scrollView.contentInset;
        
		isEndLoad = YES;		//初始时禁止加载
		
		CGSize size = [UIScreen mainScreen].bounds.size;
		
        _viewRefresh = [[NSBundle mainBundle] loadNibNamed:@"MRRefreshView" owner:nil options:nil][0];
		_viewRefresh.hidden = YES;
        _viewRefresh.alpha = 0;
        _viewRefresh.frame = CGRectMake(0, -size.width * .25, _scrollView.bounds.size.width, size.width * .25);
        
        _viewLoad = [[NSBundle mainBundle] loadNibNamed:@"MRRefreshView" owner:nil options:nil][1];
		_viewLoad.hidden = YES;
        _viewLoad.alpha = 0;
        _viewLoad.frame = CGRectMake(0, 0, _scrollView.bounds.size.width, size.width * .25);
        
        [_scrollView addSubview:_viewRefresh];
        [_scrollView addSubview:_viewLoad];
        
        //检测滚动通知
		[_scrollView addObserver:self forKeyPath:@"contentOffset" options:0 context:nil];
		[_scrollView addObserver:self forKeyPath:@"contentInset" options:0 context:nil];
        [_scrollView.panGestureRecognizer addObserver:self forKeyPath:@"state" options:0 context:nil];
    }
    
    return self;
}

- (void)dealloc
{
	_target[0] = _target[1] = _target[2] = nil;
	_action[0] = _action[1] = _action[2] = nil;
	
	[_scrollView removeObserver:self forKeyPath:@"contentOffset"];
	[_scrollView removeObserver:self forKeyPath:@"contentInset"];
    [_scrollView.panGestureRecognizer removeObserver:self forKeyPath:@"state"];
}

/*===================================================================
 说明：
    观察属性值已变更
 ==================================================================*/
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if (isBusy) return;
    
    if ([keyPath isEqualToString:@"contentOffset"])
    {
        [self scrollViewDidScroll];
    }
	else if ([keyPath isEqualToString:@"contentInset"])
	{
		if (!_edgeValid)
		{
			_edgeValid = YES;
			_edgeInset = _scrollView.contentInset;
		}
	}
    else if (_scrollView.panGestureRecognizer.state == UIGestureRecognizerStateEnded)
    {
		[self scrollViewDidEndDragging];
    }
}

/*===================================================================
 说明:
	更新约束
 ==================================================================*/
- (void)layoutIfNeeded
{
	if ([_scrollView isKindOfClass:[UITableView class]])
	{
		UITableView *view = (UITableView *)_scrollView;
		
		[view.tableHeaderView layoutIfNeeded];
		[view.tableFooterView layoutIfNeeded];
	}
}

#pragma mark - 刷新处理
/*===================================================================
 说明:
    手动刷新
 ==================================================================*/
- (void)manualRefresh
{
    if (_target[0] && _action[0])
    {
        [UIView animateWithDuration:ANIMATEDURATION animations:^{
			
			isBusy = isEndLoad = YES;
			
			UIEdgeInsets insets = _edgeInset;
			insets.top += _viewRefresh.bounds.size.height;
			
			[UIView animateWithDuration:ANIMATEDURATION animations:^{
				
				_scrollView.contentInset = insets;
				_viewRefresh.alpha = 1;
				_viewRefresh.hidden = NO;
				
				[self layoutIfNeeded];
			}];
			
            _viewRefresh.status = MRRefreshWorking;
        }];
		
        [self performSelector:@selector(performAction:) withObject:@0 afterDelay:ANIMATEDURATION inModes:@[NSRunLoopCommonModes]];
    }
}

/*===================================================================
 说明:
    完成刷新/加载
 ==================================================================*/
- (void)endLoading:(BOOL)end
{
    [UIView animateWithDuration:ANIMATEDURATION animations:^{
		
		_viewRefresh.alpha = 0;
        _viewLoad.alpha = 0;
		
		_scrollView.contentInset = _edgeInset;
		
        [self layoutIfNeeded];
        
    } completion:^(BOOL finished) {
		
		isBusy = NO;
        isEndLoad = end;
        
        _viewRefresh.status = MRRefreshNormal;
        _viewRefresh.hidden = YES;
        
        _viewLoad.status = MRRefreshNormal;
        _viewLoad.hidden = YES;
    }];
}

- (void)endRefreshing
{
    [self endLoading:YES];
}

/*===================================================================
 说明：
    拖动视图处理
 ==================================================================*/
- (void)scrollViewDidScroll
{
	_viewLoad.frame = CGRectMake(0, _scrollView.contentSize.height, _scrollView.contentSize.width, _viewLoad.frame.size.height);
	
	//显示下拉刷新
	if (_target[0] && _action[0])
	{
		_viewRefresh.hidden = _scrollView.contentOffset.y >= -_scrollView.contentInset.top;
		_viewRefresh.alpha  = _viewRefresh.hidden ? 0 : 1;
	}
	
    //下拉刷新检测
    if (_action[0] && !_viewRefresh.hidden)
    {
        if ((_scrollView.contentOffset.y + _scrollView.scrollIndicatorInsets.top) < _viewRefresh.frame.origin.y)
        {
            if (_viewRefresh.status != MRRefreshRelease) _viewRefresh.status = MRRefreshRelease;
        }
        else if (_viewRefresh.status == MRRefreshRelease)
        {
            _viewRefresh.status = MRRefreshNormal;
        }
    }
	
	//显示上拉加载
	if (!isEndLoad && (_action[1] || _action[2]))
	{
		_viewLoad.hidden = _scrollView.contentOffset.y <= _scrollView.contentSize.height - _scrollView.bounds.size.height;
		if (_scrollView.contentSize.height <= _scrollView.bounds.size.height) _viewLoad.hidden = YES;
		
		_viewLoad.alpha  = _viewLoad.hidden ? 0 : 1;
	}
	
    //上拉加载检测(自动加载)
    if (_action[2] && !isEndLoad && !_viewLoad.hidden)
    {
        if (_scrollView.contentOffset.y > _scrollView.contentSize.height - _scrollView.bounds.size.height * 1.25)
        {
            isBusy = YES;
            _viewLoad.status = MRRefreshWorking;
            [self performAction:@2];
        }
    }
	
    //上拉加载检测(手动加载)
    else if (_action[1] && !isEndLoad && !_viewLoad.hidden)
    {
        if (CGRectGetMaxY(_scrollView.bounds) > CGRectGetMaxY(_viewLoad.frame) + _scrollView.scrollIndicatorInsets.bottom)
        {
            if (_viewLoad.status != MRRefreshRelease) _viewLoad.status = MRRefreshRelease;
        }
        else if (_viewLoad.status == MRRefreshRelease)
        {
            _viewLoad.status = MRRefreshNormal;
        }
    }
}

/*===================================================================
 说明:
    松开滚动
 ==================================================================*/
- (void)scrollViewDidEndDragging
{
    if (_action[0] && _viewRefresh.status == MRRefreshRelease)       //下拉刷新
    {
        isBusy = isEndLoad = YES;
        _viewRefresh.status = MRRefreshWorking;
        
        [UIView animateWithDuration:ANIMATEDURATION animations:^{
			UIEdgeInsets edgeInset = _edgeInset;
            edgeInset.top += _viewRefresh.bounds.size.height;
            
            _scrollView.contentInset = edgeInset;
            [self.scrollView layoutIfNeeded];
        }];
		
        [self performSelector:@selector(performAction:) withObject:@0 afterDelay:ANIMATEDURATION inModes:@[NSRunLoopCommonModes]];
    }
    else if (!isEndLoad && _action[1] && _viewLoad.status == MRRefreshRelease)     //手动上拉加载
    {
        isBusy = YES;
        _viewLoad.status = MRRefreshWorking;
        
        [UIView animateWithDuration:ANIMATEDURATION animations:^{
            UIEdgeInsets edgeInset = _edgeInset;
            edgeInset.bottom += _viewLoad.bounds.size.height;
            
            _scrollView.contentInset = edgeInset;
            [self.scrollView layoutIfNeeded];
        }];
		
        [self performSelector:@selector(performAction:) withObject:@1 afterDelay:ANIMATEDURATION inModes:@[NSRunLoopCommonModes]];
    }
}

#pragma mark - 目标执行
/*===================================================================
 说明:
    执行事件
 ==================================================================*/
- (void)performAction:(NSNumber *)index
{
    #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    [_target[index.intValue] performSelector:_action[index.intValue] withObject:self];
}

/*===================================================================
 说明:
    添加事件
 ==================================================================*/
- (void)setTarget:(id)target action:(SEL)action type:(MRRefreshAction)type
{
    _target[(int)type] = target;
    _action[(int)type] = action;
}

@end
